/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "sle_hal_test_entry.h"
#include "sle_loader_hal.h"
#include "sle_host_hal.h"

static SleHostHalCallbacks *g_sleHostHalUtCbs;

void OnSleHalEnableTestCallback(SleHalErrorCode errCode)
{
    SLE_UT_LOG("[SleHostHalTest][PASSED] OnSleHalEnableTestCallback(%d)\n", errCode);
}

void OnSleHalDisableTestCallback(SleHalErrorCode errCode)
{
    SLE_UT_LOG("[SleHostHalTest][PASSED] OnSleHalDisableTestCallback(%d)\n", errCode);
}

void InitSleHostHalTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = InitSleHostHal();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] InitSleHostHalTestLevel0 failed(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] InitSleHostHalTestLevel0 pass");
}

void DeinitSleHostHalTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = DeinitSleHostHal();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] DeinitSleHostHalTestLevel0 failed(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] DeinitSleHostHalTestLevel0 pass");
}

void SleHalEnableSleTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = SleHostHalEnableSle();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalEnableSleTestLevel0 failed(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalEnableSleTestLevel0 pass");
}

void SleHalDisableSleTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = SleHostHalDisableSle();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalDisableSleTestLevel0 failed(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalDisableSleTestLevel0 pass");
}

static SleDeviceAddress publicAddr = {
    .addrType = SLE_PUBLIC_ADDRESS_TYPE,
    .addr = {'p', 'u', 'b', 'a', 'd', 'd'}
};
static SleDeviceAddress randomAddr = { 
    .addrType = SLE_RANDOM_ADDRESS_TYPE,
    .addr = {'r', 'a', 'n', 'a', 'd', 'd'}
};
void SleHalSetHostAddressTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = SleHostHalSetHostAddress(&publicAddr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalSetHostAddressTestLevel0 failed1(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalSetHostAddressTestLevel0 pass");

    ret = SleHostHalSetHostAddress(&randomAddr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalSetHostAddressTestLevel0 failed2(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalSetHostAddressTestLevel0 pass");
}

void SleHalGetHostAddressTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    SleDeviceAddress addr;
    addr.addrType = SLE_PUBLIC_ADDRESS_TYPE;
    ret = SleHostHalGetHostAddress(&addr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalGetHostAddressTestLevel0 failed1(%d)", ret);
    int cmpResult = memcmp(&addr, &publicAddr, sizeof(SleDeviceAddress));
    SLE_UT_CHECK_AND_PRINT_LOG(cmpResult == 0, "[SleHostHdiTest][FAILED] get publicAddr wrong(%s)\n", addr.addr);

    addr.addrType = SLE_RANDOM_ADDRESS_TYPE;
    ret = SleHostHalGetHostAddress(&addr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalGetHostAddressTestLevel0 failed2(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalGetHostAddressTestLevel0 pass");
    cmpResult = memcmp(&addr, &randomAddr, sizeof(SleDeviceAddress));
    SLE_UT_CHECK_AND_PRINT_LOG(cmpResult == 0, "[SleHostHalTest][FAILED] get randomAddr wrong(%s)\n", addr.addr);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalGetHostAddressTestLevel0 pass");
}

static uint8_t g_hostName[SLE_DEVICE_NAME_LEN] = {'h', 'd', 'i', 'U', 'T', 'h', 'o', 's', 't', 'n', 'a', 'm', 'e', '\0'};
void SleHalSetHostNameTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = SleHostHalSetHostName(g_hostName, SLE_DEVICE_NAME_LEN);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalSetHostNameTestLevel0 failed(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalSetHostNameTestLevel0 pass");
}

void SleHalGetHostNameTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    uint8_t name[SLE_DEVICE_NAME_LEN] = {0};
    uint8_t len = SLE_DEVICE_NAME_LEN;
    ret = SleHostHalGetHostName(name, &len);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalGetHostNameTestLevel0 failed(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalGetHostNameTestLevel0 pass");
}

void SleHostHalRegisterCallbackTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = SleHostHalRegisterCallback(g_sleHostHalUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHostHalRegisterCallbackTestLevel0 failed(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHostHalRegisterCallbackTestLevel0 pass");
}

/** SleHostHal Unit Test with correct input param*/
void SleHostHalTestLevel0(void)
{
    SLE_UT_LOG("___SleHostHalTestLevel0 start");
    InitSleHostHalTestLevel0();
    SleHostHalRegisterCallbackTestLevel0();
    SleHalEnableSleTestLevel0();
    SleHalSetHostAddressTestLevel0();
    SleHalGetHostAddressTestLevel0();
    SleHalSetHostNameTestLevel0();
    SleHalGetHostNameTestLevel0();
    SleHalDisableSleTestLevel0();
    DeinitSleHostHalTestLevel0();
    SLE_UT_LOG("___SleHostHalTestLevel0 end");
}

void InitSleHostHalTestLevel1(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = InitSleHostHal();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] InitSleHostHalTestLevel1 failed(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] InitSleHostHalTestLevel1 pass1");
    //测试重复调用
    ret = InitSleHostHal();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] InitSleHostHalTestLevel1 failed(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] InitSleHostHalTestLevel1 pass2");
}

void DeinitSleHostHalTestLevel1(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = DeinitSleHostHal();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] DeinitSleHostHalTestLevel1 failed(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] InitSleHostHalTestLevel1 pass1");
    //测试重复调用
    ret = DeinitSleHostHal();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] DeinitSleHostHalTestLevel1 failed(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] InitSleHostHalTestLevel1 pass2");
}

void SleHalEnableSleTestLevel1(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = SleHostHalEnableSle();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalEnableSleTestLevel1 failed(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalEnableSleTestLevel1 pass1");
}

void SleHalDisableSleTestLevel1(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = SleHostHalDisableSle();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalDisableSleTestLevel1 failed(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalEnableSleTestLevel1 pass2");
}

void SleHalSetHostAddressTestLevel1(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    SleDeviceAddress addr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
        .addr = {'p', 'u', 'b', 'a', 'd', 'd'}
    };
    //测试入参为NULL
    ret = SleHostHalSetHostAddress(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_ERR_INVALID_PARAM, "[SleHostHalTest][FAILED] SleHalSetHostAddressTestLevel1 failed1(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalSetHostAddressTestLevel1 pass1");

    addr.addrType = SLE_PUBLIC_ADDRESS_TYPE;
    ret = SleHostHalSetHostAddress(&addr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalSetHostAddressTestLevel1 failed2(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalSetHostAddressTestLevel1 pass2");

    addr.addrType = SLE_RANDOM_ADDRESS_TYPE;
    ret = SleHostHalSetHostAddress(&addr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalSetHostAddressTestLevel1 failed3(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalSetHostAddressTestLevel1 pass3");
}

void SleHalGetHostAddressTestLevel1(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    SleDeviceAddress addr;
    addr.addrType = 255;
    //测试入参为NULL
    ret = SleHostHalGetHostAddress(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_ERR_INVALID_PARAM, "[SleHostHalTest][FAILED] SleHalGetHostAddressTestLevel1 failed1(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalGetHostAddressTestLevel1 pass1");

    addr.addrType = SLE_PUBLIC_ADDRESS_TYPE;
    ret = SleHostHalGetHostAddress(&addr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalGetHostAddressTestLevel1 failed2(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalGetHostAddressTestLevel1 pass2");

    addr.addrType = SLE_RANDOM_ADDRESS_TYPE;
    ret = SleHostHalGetHostAddress(&addr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalGetHostAddressTestLevel1 failed3(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalGetHostAddressTestLevel1 pass3");
}

void SleHalSetHostNameTestLevel1(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    //测试入参为NULL
    ret = SleHostHalSetHostName(NULL, SLE_DEVICE_NAME_LEN);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_ERR_INVALID_PARAM, "[SleHostHalTest][FAILED] SleHalSetHostNameTestLevel1 failed1(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalSetHostNameTestLevel1 pass1");

    ret = SleHostHalSetHostName(g_hostName, SLE_DEVICE_NAME_LEN);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalSetHostNameTestLevel1 failed2(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalSetHostNameTestLevel1 pass2");
    SleHalSetHostNameTestLevel0();
}

void SleHalGetHostNameTestLevel1(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    uint8_t name[SLE_DEVICE_NAME_LEN] = {0};
    uint8_t len = SLE_DEVICE_NAME_LEN;
    //测试入参为NULL
    ret = SleHostHalGetHostName(NULL, &len);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_ERR_INVALID_PARAM, "[SleHostHalTest][FAILED] SleHalGetHostNameTestLevel1 failed1(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalGetHostNameTestLevel1 pass1");
    ret = SleHostHalGetHostName(g_hostName, NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_ERR_INVALID_PARAM, "[SleHostHalTest][FAILED] SleHalGetHostNameTestLevel1 failed2(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalGetHostNameTestLevel1 pass2");

    ret = SleHostHalGetHostName(name, &len);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHalGetHostNameTestLevel1 failed3(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalGetHostNameTestLevel1 pass3");
}

void SleHalRegisterHostCallbackTestLevel1(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    //测试入参为NULL
    ret = SleHostHalRegisterCallback(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_ERR_INVALID_PARAM, "[SleHostHalTest][FAILED] SleHalRegisterHostCallbackTestLevel1 failed1(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalRegisterHostCallbackTestLevel1 pass1");

    ret = SleHostHalRegisterCallback(g_sleHostHalUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleHostHalTest][FAILED] SleHostHalRegisterCallbackTestLevel0 failed2(%d)", ret);
    SLE_UT_LOG("[SleHostHalTest][PASSED] SleHalRegisterHostCallbackTestLevel1 pass2");
}

void SleHostHalTestLevel1(void)
{
    SLE_UT_LOG("___SleHostHalTestLevel1 start");
    InitSleHostHalTestLevel1();
    SleHalRegisterHostCallbackTestLevel1();
    SleHalEnableSleTestLevel1();
    SleHalSetHostAddressTestLevel1();
    SleHalGetHostAddressTestLevel1();
    SleHalSetHostNameTestLevel1();
    SleHalGetHostNameTestLevel1();
    SleHalDisableSleTestLevel1();
    DeinitSleHostHalTestLevel1();
    SLE_UT_LOG("___SleHostHalTestLevel1 end");
}

SleHalErrorCode InitSleHostHalTestEntry(void)
{
    g_sleHostHalUtCbs = (SleHostHalCallbacks*)malloc(sizeof(SleHostHalCallbacks));
    g_sleHostHalUtCbs->OnHostHalEnableSleCb = OnSleHalEnableTestCallback;
    g_sleHostHalUtCbs->OnHosthalDisableSleCb = OnSleHalDisableTestCallback;
    if(g_sleHostHalUtCbs == NULL) {
        SLE_UT_LOG("[SleHostHalTest][FAILED] malloc g_sleHostHalUtCbs failed");
        return SLE_HAL_ERR_DRIVER_OR_SYSTEM;
    }
    return SLE_HAL_SUCCESS;
}

SleHalErrorCode DeinitSleHostHalTestEntry(void)
{
    free(g_sleHostHalUtCbs);
    g_sleHostHalUtCbs = NULL;
    return SLE_HAL_SUCCESS;
}

void SleHostHalTestEntry(void)
{
    SLE_UT_LOG("__SleHostHalTestEntry start");
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = InitSleHostHalTestEntry();
    SLE_UT_CHECK_AND_RETURN(ret == SLE_HAL_SUCCESS);
    SleHostHalTestLevel0();
    SleHostHalTestLevel1();
    ret = DeinitSleHostHalTestEntry();
    SLE_UT_CHECK_AND_RETURN(ret == SLE_HAL_SUCCESS);
    SLE_UT_LOG("__SleHostHalTestEntry end");
}